import { _decorator, Collider2D, Color, Component, Contact2DType, Label, misc, MotionStreak, Node, SpriteFrame, sys, Texture2D, UITransform, Vec2, Vec3 } from 'cc';
import { Unit, UnitEvent } from './Unit';
import { SpawnerCom } from './Component/SpawnerCom';
import { Global, UnitType } from '../Util/Global';
import { Drawlayer, UICtrl } from '../Ctrl/UICtrl';
import { Bullet } from './Bullet';
import { FactoryCom } from './Component/FactoryCom';
import AssetsMgr from '../Model/AssetsMgr';
import GameEventMgr, { GameEvent } from '../Model/GameEventMgr';
const { ccclass, property } = _decorator;

/**飞行器基类 */
@ccclass('UnitSpacecraftBase')
export class UnitSpacecraftBase extends Unit {

    @property({ displayName: "基础索敌范围", override: true })
    alertFieldRadius: number = 10;
    /**距离母舰的额外活动范围 */
    @property({ displayName: "额外活动距离" })
    public actionRange: number = 0;
    public canPlanetHit: boolean = false;

    /**兵器工厂 */
    public arsenal: SpawnerCom = null;

    protected trigger: Collider2D = null;

    protected targetList: Map<Unit, number> = new Map();

    protected trail: Node = null;

    private _target: Unit = null;

    set target(value: Unit) {
        if (value && this.unitType != UnitType.UnitMining && !this.IsEnemy(value)) {
            // console.log('警告==>不是敌人！', this.uuid, value.uuid);
        }
        this._target = value;
        if (!this._target && this.arsenal) {
            this.arsenal.ClearWorkShop();
        }
    }

    get target() {
        return this._target;
    }

    // protected onParentDestroy() {
    //     this.deathTime = 1;
    // }

    AddTarget(t: Unit) {
        let observedFrequency = this.targetList.get(t) || 0;
        this.targetList.set(t, observedFrequency + 1);
    }

    LostTarget(t: Unit) {
        if (t == this.target) {
            this.target = null;
        }
        let observedFrequency = this.targetList.get(t) || 0;

        observedFrequency -= 1;

        if (observedFrequency <= 0) {
            this.targetList.delete(t);
        }
        else {
            this.targetList.set(t, observedFrequency);
        }
    }

    protected onBeforeParentUnitChange(beforeUnit: Unit, currentUnit: Unit): void {

        if (beforeUnit && beforeUnit != currentUnit && !beforeUnit.death) {
            beforeUnit.off(this, UnitEvent.OnDestroy);
        }
        if (currentUnit) {
            currentUnit.on(this, UnitEvent.OnDestroy, () => {
                // this.deathTime = 1;
                this.DestroySelf('父级销毁');
            });
        }
    }

    /**选择序列大的、或者距离近的目标优先 */
    FindTargetWeightAndNearest(newEnemy?: Unit): Unit {
        let tempDis = 0;

        if (newEnemy && this.target && !this.target.death) {//检测是否需要更换目标
            tempDis = this.DistanceOther(this.target);
            if (this.target.unitType > newEnemy.unitType || tempDis < this.DistanceOther(newEnemy)) {
                return this.target;
            }
            else {
                return newEnemy;
            }
        }

        let weightOrNearestUnit = null;
        let unValidUnits: Unit[] = [];//无效目标
        for (let kv of this.targetList) {
            if (!kv[0].death && this.IsEnemy(kv[0])) {
                let dis = this.DistanceOther(kv[0]);
                if ((weightOrNearestUnit && weightOrNearestUnit.unitType < kv[0].unitType)
                    || tempDis == 0
                    || dis < tempDis) {

                    tempDis = dis;
                    weightOrNearestUnit = kv[0];
                }
            }
            else {
                unValidUnits.push(kv[0]);
            }
        }

        for (let i = 0; i < unValidUnits.length; i++) {
            this.targetList.delete(unValidUnits[i]);
            if (weightOrNearestUnit == null && newEnemy && unValidUnits[i] == newEnemy) {
                if (newEnemy.destructable) {
                    if (newEnemy.destructable.next_remain_hp > 0) {
                        // console.log('警告==>新可存活目标但被忽略！！？', newEnemy.destructable.next_remain_hp);
                    }
                    else if (newEnemy.hp <= 0) {

                        console.log('警告==>新目标已死亡怎么没销毁！！？', newEnemy.hp);
                    }
                    unValidUnits[i].death;
                }
            }
        }

        return weightOrNearestUnit;
    }

    protected rendererUpdate_Gravity_Velocity(dt: number): void {
        if (Global.LinearVelocityRenderer && this.speedS > 10) {
            // let endPos = this._moveVec.clone().multiplyScalar(this.speedS / 5); // 终点坐标
            let endPos = this.rigBody.linearVelocity.clone().normalize().multiplyScalar(this.speedS / 5); // 终点坐标
            UICtrl.LineRenderer(this.unitWorldPos, this.unitWorldPos.add(this.ToVec3(endPos)), Color.RED, Drawlayer.View);
        }

        if (Global.GravityCricleRenderer) {
            UICtrl.CircleRenderer(this.unitWorldPos, this.alertFieldRadius / Global.CameraOrthoScale, Color.BLUE);
        }
    }

    protected start(): void {
        super.start();

        this.arsenal = this.getComponent(SpawnerCom);
        if (this.arsenal) {
            this.arsenal.unit = this.parentUnit;
        }

        for (let co of this.colliders) {
            if (co.tag == 1) {
                this.trigger = co;
                this.trigger.radius = this.alertFieldRadius;

                //监听传感器碰撞事件 二者的rigibody和collider二者任意一个的group符合碰撞就会触发碰撞事件
                this.trigger.on(Contact2DType.BEGIN_CONTACT, this.onTriggerEnter, this);
                this.trigger.on(Contact2DType.END_CONTACT, this.onTriggerExit, this);

                break;
            }
        }

        this.collider.on(Contact2DType.BEGIN_CONTACT, this.onColliderEnter, this);
        GameEventMgr.Register(this, GameEvent.EconomicComBroken, this.OnEnemyEconmicBroken.bind(this));

        if (sys.isBrowser) {
            let node = new Node;
            node.parent = this.node;
            node.setPosition(50, -50);
            let label = node.addComponent(Label);
            label.string = this.uuid.slice(5, 11);
            label.fontSize = 20;
            node.active = Global.TrackerDebug;
            GameEventMgr.Register(this, GameEvent.OnTrackerDebug, () => {
                node.active = Global.TrackerDebug;
            })
        }

        this.trail = this.node.getChildByName('trail');
        this.startLogic();
    }

    OnEnemyEconmicBroken(unit: Unit) {

        this.LostTarget(unit);
        if (unit != null && unit == this.parentUnit) {
            this.parentUnit = null;
        }
    }

    /**替代start，不会影响下基类的start逻辑 */
    protected startLogic() {
    }

    protected lateStart(): void {
        super.lateStart();

    }

    protected onDisable(): void {
        super.onDisable();

        this.targetList.clear();
        this._target = null;
        if (this.arsenal) {
            this.arsenal.ClearWorkShop();
        }
        this.parentUnit = null;
        this._moveVec.set(0, 0);
    }

    protected _updateLogic(dt: number): void {
        super._updateLogic(dt);

        if (this.parentUnit == null) {
            this.DestroySelf('没有母星了怎么还在啊！？');
        }

        if (this.trail) {
            this.trail.active = this.isInScreenPos;
        }

        this.updateLogic(dt);
    }

    /**替代update，不会影响下基类的update逻辑 */
    protected updateLogic(dt: number): void {

    }

    protected checkMaxLimitVelocity() {
        let maxSp = this.maxSpeed;
        if (this.TooFarFromParent()) {
            maxSp = this.maxSpeed + this.parentUnit.speed;
        }

        if (this.speed > maxSp) {//暂时设置最大速度
            let v = this.rigBody.linearVelocity.clone().normalize().multiplyScalar(maxSp);
            this.rigBody.linearVelocity = v;
        }
    }

    protected onDestroy(): void {

        this.trigger.off(Contact2DType.BEGIN_CONTACT, this.onTriggerEnter, this);
        this.trigger.off(Contact2DType.END_CONTACT, this.onTriggerExit, this);

        this.collider.off(Contact2DType.BEGIN_CONTACT, this.onColliderEnter, this)
    }

    //虽然子弹是触发器 但是自身碰撞体和子弹的分组符合碰撞条件也会触发
    protected onColliderEnter(selfCollider: Collider2D, otherCollider: Collider2D) {
        super.onColliderEnter(selfCollider, otherCollider);
        let other = otherCollider.node.getComponent(Unit);

        if (other) {
            if (other.unitType == UnitType.UnitAsteroid && this.canPlanetHit) {
                this.DestroySelf();//被小行星撞击
            }
            //子弹攻击放到伤害发生组件里
            // else if (other.parentUnit != this.parentUnit && other != this.parentUnit) {
            //     // console.log(this.parentUnit, other.parentUnit)
            //     if (other.unitType == UnitType.Bullet) {
            //         let bullet = <Bullet>other;
            //         this.hp -= bullet.atk;
            //         if (this.hp <= 0) {
            //             this.DestroySelf();
            //         }
            //     }
            // }
        }
    }

    /**移动方向 */
    protected _moveVec = new Vec2();

    //改变移动方向
    ChangeMoveDir(back?: boolean) {
        let temp = null;
        if (!back) {
            temp = this.GetRandomPointInCircle();
        }
        else if (this.parentUnit) {
            this.target = null;
            temp = this.parentUnit.unitWorldPos;
        }
        // 计算物体需要移动的距离和方向
        let moveDir = temp.subtract(this.unitWorldPos).normalize();//向量减法会改变自身

        this._moveVec.x = moveDir.x;
        this._moveVec.y = moveDir.y;
    }

    //随机目的地（世界坐标）
    GetRandomPointInCircle() {

        // 生成随机角度（-90到90度之间）
        let angle = misc.degreesToRadians(((Math.random() * 2) - 1) * 70);
        // 使用三角函数计算坐标
        let x = Math.cos(angle);
        let y = Math.sin(angle);

        let pos = new Vec3(x, y, 0);
        this.GetRotatedPos(pos);

        if (this.TooFarFromParent()) {
            let parentPos = this.getComponent(UITransform).convertToNodeSpaceAR(this.parentUnit.unitWorldPos).normalize();
            pos.add(parentPos);
        }
        this.getComponent(UITransform).convertToWorldSpaceAR(pos, pos);

        return pos;
    }

    /**离开母舰太远 */
    TooFarFromParent(): boolean {
        return this.parentUnit && this.DistanceOther(this.parentUnit) > this.parentUnit.alertFieldRadius + this.actionRange;
    }

    //追逐目标
    ChangeChaseTargetDir() {

        let temp = this.target.unitWorldPos;
        let moveDir = temp.subtract(this.unitWorldPos).normalize();//向量减法会改变自身

        this._moveVec.x = moveDir.x;
        this._moveVec.y = moveDir.y;
    }

    //环绕目标
    SurroundTargetDir() {
        let toTarget = this.GetDirToOther(this.target).normalize();

        this._moveVec.x = -toTarget.y;
        this._moveVec.y = toTarget.x;
    }

    AutoMove() {

        this._moveVec.normalize().multiplyScalar(1 + this.moveAcceleration);

        let newSpeedVec = this.rigBody.linearVelocity.add(this._moveVec);

        this.rigBody.linearVelocity = newSpeedVec;

        //在lateupdate中有最大限制
        // let maxSp = this.maxSpeed;
        // if (this.parentUnit) {
        //     maxSp = this.maxSpeed + this.parentUnit.speed;
        // }
        // if (this.speed > maxSp) {//暂时设置最大速度
        //     let v = this.rigBody.linearVelocity.clone().normalize().multiplyScalar(maxSp);
        //     this.rigBody.linearVelocity = v;
        // }

        let angle = this.rigBody.linearVelocity.signAngle(this.forward) * 180 / Math.PI;
        this.node.setRotationFromEuler(0, 0, -angle); //= Quat.fromEuler(this.node.rotation,0, 0, -angle);
    }

    IsEnemy(unit: Unit) {
        if (!unit) {
            return false;
        }
        if (unit.unitType == UnitType.UnitPlanet) {
            if (unit.getComponent(FactoryCom) == null) {
                return false;
            }

            if (unit && unit != this.parentUnit) {//对方和自己不来自一个父级
                return true;
            }
        }
        else if (!unit ||
            !(unit.unitType > UnitType.Bullet && unit.unitType <= UnitType.UnitSpacecra)) {
            return false;
        }
        if (unit && unit.parentUnit != this.parentUnit && unit != this.parentUnit) {//对方和自己不来自一个父级
            return true;
        }
        return false;
    }
}


